<!DOCTYPE html>
<html lang="zh-CN"><head><title>帮助</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head>
<body>
<center>
<table width=780 border=0 cellpadding=3 cellspacing=0>
<tr><td style='line-height:150%;font-size:16px;text-indent: 20px'>
<p><a href="#" onclick="window.history.back()">返回</a></p>

<p align=center><b>第二章 公历与儒略日</b></p>

<p><b>概述</b></p>
<p>选自本人的《天文算法》部分译文</p>
<p>公历中规定平年有365日，闰年366日。每年含有12个月。</p>
<p>在1582年10月4日以前，公历规定每4年设置一个闰年，平均年长度为365.25天，这期间的公历称为儒略历。在1582年10月15日之后则规定每400年97闰，平均年长度为365.2425天，这期间的公历称之为格里高利历。  格里高利历并非在所有国家迅速得到一致采用，这一点在历史研究中要引起注意。例如在大不列颠，晚至公元1752年才变更历法，而土耳其则要等到1927年。</p>
<p>由于儒略历存在严重的“多闰”问题，到了1582年，公历跑快了10天左右，当时就人为调整了10天，并从此改用格里历。因此务必注意1582年10月4日（儒略历）的下一日为1582年10月15日（格里高利历）。也就是说1582年10月份少了10天。</p>

<p><b>闰年的具体设置</b></p>
<p>在儒略历中，能被4整除的年份为闰年，这一年有366天，其它年份为平年（365天）。 如900年和1236年为闰年，而750年和1429年为平年。</p>
<p>格里高利历法也采用这一规则，但下列年份除外：不能被400整除的百年为平年，如1700年，1800年，1900年和2100年。其余能被400整除的年份则为闰年，如1600年，2000年和2400年。 </p>

<p><b>儒略历的扩展</b></p>
<p>儒略历由尤里乌斯·恺撒于公元前45年在罗马帝国创立，而其最终形式确立于公元8年前后，尽管如此，我们仍可以借助天文学家的演算无止境地向前推算儒略历。比如在这一系统中，我们可以说某次日食发生在公元前1203年8月28日，虽然在那个遥远的年代，罗马帝国根本还未被创建，而8月这个月份更有待设立。</p>
<p>对于公元1年之前年份的纪年方法，天文学家同历史学家并不一致。天文纪年中，+1年的前一年为0年，再之往前1年是-1年。所以历史学家所说的公元前585年实际上是-584年。</p>
<p>天文上以负数纪年只是为了计算方便。比如，在历史学纪年中的，可被4整除的年份为儒略历闰年这个规则不再有效了，如公元前1，5，9，13，…在天文纪年中它们却被记为0，-4，-8，-12 …，都能被4整除。</p>
<p>我们以INT(x)来表示数x的整数部分，即小数点前的整数。例如：</p>
<p>INT(7/4) = 1   INT(5.02) = 5</p>
<p>INT(8/4) = 2   INT(5.9999) = 5</p>
<p>对于负数，这里的INT(x)指小于等于x的最大整数。那样的话就有INT(-7.83) = -8。如果你的程序是javascript，取整函数是 Math.floor(x)，它返回小于等于x的最大整数。如果你用的是C++，那么用 (int)x 强制转换，得到是的整数部分，而不是小于等于x的最大整数。

<p><b>儒略日数（简称儒略日）</b></p>
<p>儒略日数是指从公元 -4712 年开始连续计算日数得出的天数及不满一日的小数，通常记为 JD (**)。传统上儒略日的计数是从格林尼治平午，即世界时12点开始的。若以力学时（或历书时）为标尺，这种计数通常表达为“儒略历书日”，即JDE (**)，其中E只是一种表征，即按每天86400个标准秒长严格地计日。例如：</p>
<p>1977年4月26.4日 UT = JD 2443 259.9</p>
<p>1977年4月26.4日 TD = JDE 2443 259.9</p>

<p><b>儒略日的计算</b></p>
<p>设Y为给定年份，M为月份，D为该月日期（可以带小数）。</p>
<p>若M > 2，Y和M不变，若 M =1或2，以Y–1代Y，以M+12代M，换句话说，如果日期在1月或2月，则被看作是在前一年的13月或14月。</p>
<p>对格里高利历有 ：A = INT（Y/100）   B = 2 - A + INT(A/4)</p>
<p>对儒略历，取 B = 0</p>
<p>要求的儒略日即为：JD = INT(365.25(Y+4716))+INT(30.6001(M+1))+D+B-1524.5</p>
<p>使用数值30.6取代30.6001才是正确的，但我们仍使用30.6001，以确保总能取得恰当的整数。事实上可用30.601甚至30.61来取代30.6001。例如，5乘30.6精确等于153，然而大多数计算机不能精确表示出30.6，这导致得出一个152.999 9998的结果，它的整数部分为152，如此算出的JD就不正确了。</p>
<p>
下表列出了一些历日所对应的儒略日，可作测试程序之用。<br>
 2000年 1月 1.5日 2451 545.0<br>
 1987年 1月27.0日 2446 822.5<br>
 1987年 6月19.5日 2446 966.0<br>
 1988年 1月27.0日 2447 187.5<br>
 1988年 6月19.5日 2447 332.0<br>
 1900年 1月 1.0日 2415 020.5<br>
 1600年 1月 1.0日 2305 447.5<br>
 1600年12月31.0日 2305 812.5<br>
  837年 4月10.3日 2026 871.8<br>
-1000年 7月12.5日 1356 001.0<br>
-1000年 2月29.0日 1355 866.5<br>
-1001年 8月17.9日 1355 671.4<br>
-4712年 1月 1.5日 0.0 
</p>


<p><b>由儒略日推算历日</b></p>

<p>将JD加上0.5，令 Z 为其整数部分，F 为尾数（小数）部分。</p>
<p>若 Z < 2299161，取A = Z</p>
<p>若 Z 大于等于2299 161，计算 α=INT((Z-1867216.25)/36524.25) ，A=Z+1+α-INT(α/4)</p>
<p>然后计算</p>
<p>B = A+1524</p>
<p>C = INT((B-122.1)/365.25)</p>
<p>D = INT(365.25C)</p>
<p>E = INT((B-D)/30.6001) </p>

<p>该月日期（带小数部分）则为：d = B - D - INT(30.6001E) + F</p>

<p>月份m为： <br>
IF E < 14 THEN m = E – 1 <br>
IF E=14 or E=15 THEN m = E – 13 <br>
</p>

<p>年份为y：<br>
IF m>2 THEN y = C – 4716<br>
IF m =1 or m=2 THEN y = C – 4715
</p>

<p>这个公式里求E时用的数30.6001不能代之以30.6，哪怕计算机没有先前所说的问题。否则，你得到的结果会是2月0日而不是1月31日，或者4月0日而不是3月31日。</p>


<pre>
<b>算法实现范例(JavaScript)</b>
function int2(v){ return Math.floor(v); }  //取整数部分
var JD={ //日期元件
  JD:function(y,m,d){ //公历转儒略日
   var n=0, G=0;
   if(y*372+m*31+int2(d)>=588829) G=1; //判断是否为格里高利历日1582*372+10*31+15
   if(m<=2) m+=12, y--;
   if(G) n=int2(y/100), n=2-n+int2(n/4); //加百年闰
   return int2(365.25*(y+4716)) + int2(30.6001*(m+1))+d+n - 1524.5;
  },
  DD:function(jd,r){ //儒略日数转公历
   var D=int2(jd+0.5), F=jd+0.5-D, c;  //取得日数的整数部份A及小数部分F
   if(D>=2299161) c=int2((D-1867216.25)/36524.25),D+=1+c-int2(c/4);
   D += 1524;               r.Y = int2((D-122.1)/365.25);//年数
   D -= int2(365.25*r.Y);   r.M = int2(D/30.601); //月数
   D -= int2(30.601*r.M);   r.D = D;; //日数
   if(r.M>13) r.M -= 13, r.Y -= 4715;
   else       r.M -= 1,  r.Y -= 4716;
   //日的小数转为时分秒
   F*=24; r.h=int2(F); F-=r.h;
   F*=60; r.m=int2(F); F-=r.m;
   F*=60; r.s=F;
  }
}
</pre>



<p><b>星期几的问题</b></p>
<p>在公历中，星期是按7天一个循环计日，周而复始。中国的干支记法与星期记法的算法的实现几乎完全相同。</p>
<p>给定日期是星期几可由以下方法获得 — 计算该日0时的儒略日，加上1.5，再除以7 ，所得余数将指示出星期几：若余数为0，则为星期日，1为星期一，2为星期二，3为星期三，4为星期四，5为星期五，6为星期六。 </p>
<p>儒略历到格里高利历的换算并不影响星期。因而，在1582年，10月4日星期四接下来的一天便是10月15日星期五。</p>


















</td></tr>
</table>
</center>
</body></html>
